/**
 * 协议报文
 */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "main.h"
#include "CmdBase.h"


//AT Cmd deal enter function   0x41 0x54="AT"
__attribute__((weak)) int Cmd_AT_deal(uint8_t *Cmd,uint16_t CmdLen,uint16_t *pCmdLen,void (*tx)(uint8_t *buf,int len))
{
	if(CmdLen < 2) return CMD_CONTINUE;
	if((Cmd[0] == 0x41 && Cmd[1] == 0x54) || (Cmd[0] == 0x61 && Cmd[1] == 0x74) ){ //AT...
		sprintf(strMsg, "weak Cmd AT Deal\r\n");
		tx((uint8_t *)strMsg,strlen(strMsg));
	}
	return CMD_FINISH;
}

//0x01 Msg deal enter function  //byte[] cmd_Rst = { 0x1F, 0xAA, 0x02, 0x00, 0xAB, 0x54 };
__attribute__((weak)) int Cmd_1F_deal(uint8_t *Cmd,uint16_t CmdLen,uint16_t *pCmdLen,void (*tx)(uint8_t *buf,int len))
{
	if(CmdLen < 5) return CMD_CONTINUE;

	sprintf(strMsg, "weak Cmd 1F Deal\r\n");
	tx((uint8_t *)strMsg,strlen(strMsg));
	return CMD_FINISH;
}


//Reply message deal function
__attribute__((weak))  void cmd_tx(uint8_t *buf,int len)
{
    //... write to cmd fifo or diret to comm
}

const uint8_t c_Cmd_Start[MAX_CMD_TYPE]={0x41,0x1F};  //'A' / 'a' / 0x1F
int (* gCmdHandler_Array[MAX_CMD_TYPE])(uint8_t *Cmd,uint16_t CmdLen,uint16_t *pCmdLen,void (*tx)(uint8_t *buf,int len))=
{
	&Cmd_AT_deal,
	&Cmd_1F_deal,
};

int gCmdHandler_Check(uint8_t ch)
{
	//printf("check=%x\r\n", ch);
	for(int i=0;i<MAX_CMD_TYPE;i++)
	{
		if(ch == c_Cmd_Start[i]){
			//printf("find=%x\r\n", ch);
		 	return i;
		}
	}
	return -1;
}


static __attribute__((aligned(8)))  uint8_t CmdBuf[CMD_LEN_MAX+4];   //Recieve cmd buffer
void cmd_put(uint8_t *data, int len, void (*tx)(uint8_t *buf,int len))
{
	int (*ActiveHandler)(uint8_t *Cmd,uint16_t CmdLen,uint16_t *pCmdLen, void (*tx)(uint8_t *buf,int len));
	uint16_t CmdLen;

	if(len<=0) return;
	//printf("cmd_put");
	//if(CmdTimer->read_ms()>3000)cmd_reset();
	ActiveHandler=NULL;
	CmdLen=0;
	memset(CmdBuf,0,sizeof(CmdBuf));
	if(data[len-1] != 0x0d && data[len-1] != 0x0a)
	{
		data[len] = 0x0a;
		len++;
	}
	for(int ii = 0;ii<len;ii++)
	{
		//Wdt_clr();
		uint8_t c=data[ii];
		//printf("%x,",c);
		if(ActiveHandler)
		{
			//printf("ActiveHandler\r\n");
			if(CmdLen<CMD_LEN_MAX)CmdBuf[CmdLen++]=c;
			int r=ActiveHandler(CmdBuf,CmdLen,&CmdLen,tx);
			if(r==CMD_FINISH || r==CMD_MISS_MATCH){
				ActiveHandler=NULL;
				CmdLen=0;
			}
		}
		else
		{
			int cmd_index = gCmdHandler_Check(c);
			if(cmd_index != -1)
			{
				//printf("Find=%d\r\n", cmd_index);
				if(CmdLen<CMD_LEN_MAX)CmdBuf[CmdLen++]=c;
				int r=gCmdHandler_Array[cmd_index](CmdBuf,CmdLen,&CmdLen,tx);
				if(r==CMD_CONTINUE)ActiveHandler = gCmdHandler_Array[cmd_index];
				else if(r==CMD_MISS_MATCH){
					ActiveHandler=NULL;
					CmdLen=0;
				}
			}
		}
	}

	//printf("cmd_put exit\r\n");
	//CmdTimer->reset();
}
